-
Notifications
You must be signed in to change notification settings - Fork 1.1k
fix #10997: check accessible from sealed parent not companion #11039
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about the fromProduct
method? That is not generated if there is no companion, right? How does that manifest itself?
We probably should have a test involving fromProduct
I have added a test using |
Edit: I have added a test case to prevent a crash in the following: class ClassWrapper {
sealed trait Parent
case class Foo(x: Int, y: Int, s: String) extends Parent
}
@main def Test =
val cw = new ClassWrapper()
val mirrorParent = summon[deriving.Mirror.Of[cw.Parent]] // error - dont synthesize mirror in this case If we allow this case then the generated mirror will use paths such as A temporary mitigation is included in the next commit to check accessibility from the scope of the generated mirror, a follow up PR could correct the paths generated when the mirror has a class instance in its path |
I have added a test to check that the mirror can also access the children if it is an anonymous class |
60d8038
to
6d1e7fa
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, the downside of not having a companion is that everytime you demand a mirror a new object is created, right? Which means a new class is generated per call site, and an object per dynamic call.
I think that's a serious degradation that is not at all obvious. So at least we should have a warning that this happens and an encouragement to create a companion object.
Typeclass derivation libraries often need to be high-performance, so we should make users aware of the trap.
Should this warning be for all anonymous mirrors (i.e. including mirrors for Scala 2 types) or just the ones for types in Scala 3. I would assume probably avoid noise for Scala 2 types |
646f236
to
75ab830
Compare
adding the warning is breaking shapeless though with an unrelated error |
I think I misunderstood two cases. If a trait has a derived clause sealed trait T derives C it gets a companion automatically. That's the case I was after. I thought somehow that we would then fallback to anonymous classes, but that's obviously not the case. If we summon a mirror outside, we should be prepared that an anonymous class is created. So I think we can just revert the last commit and drop the warning. Sorry for the confusion! |
I have reverted the changes to add the warning |
the problem in shapeless was that it had fatal warnings turned on which causes an error in the macro to summon a |
fixes #10997
given the commit 275a0a9 I am unclear why the accessibilty test in
whyNotGenericSum
needs to check for the companion.I believe that it was a lucky coincidence that
whyNotGenericSum
passes for traits without a companion, i.e. if you trace the owners of any definition up to the root package then eventually you get the ownerNoSymbol
, which then succeeds in the case there is no companion, which breaks the criterion "all of its children are addressable through a path from its companion object".The motivation for the change in this PR is that we use
whyNotGenericSum
to implementisGenericSum
. ThenisGenericSum
is used bySynthesizer.sumMirror
to decide if something gets a synthesizedMirror.Sum
.Since
Synthesizer.sumMirror
still generates a mirror even if there is no companion, I can not see a reason to failwhyNotGenericSum
if there is no companion.